<script src="../../canvas-test-master/src/Funny-demo/transform/demo1.js"></script>
<template>
	<view>
		<canvas type="2d" id="imageCanvasHide" canvas-id="imageCanvasHide" class="canvasHide" disable-scroll="true" />
		<canvas type="2d" ref="canvas" id="imageCanvas" canvas-id="imageCanvas" class="imageCanvas" />

		<view class="connect-box">
			<view class="connect-box-state" @click="gblink()">断开连接</view>
			<view class="connect-box-select-device" @click="selecttype()" :style="{'color': linkname.name == '需先点这里连接影描机'?'red':'#333','font-weight': '600'}" >{{ linkname.name }}</view>
		</view>

		<div class="container">
			<div class="outer-circle">
				<div class="button-outer top-left">
					<uni-icons v-for="(item, index) in typeList" v-if="index === 0" :key="index"
						:style="{transform: `rotate(${item.rotate}deg)`}"
						:type="item.check ? 'paperplane-filled' : 'paperplane' "
						:color="item.check ? '#ba0111' : 'black' " @tap="clickType(item, index)" size="35">
					</uni-icons>
				</div>
				<div class="button-outer top-right">
					<uni-icons v-for="(item, index) in typeList" v-if="index === 1" :key="index"
						:style="{transform: `rotate(${item.rotate}deg)`}"
						:type="item.check ? 'paperplane-filled' : 'paperplane' "
						:color="item.check ? '#ba0111' : 'black' " @tap="clickType(item, index)" size="35">
					</uni-icons>
				</div>
				<div class="button-outer bottom-left">
					<uni-icons v-for="(item, index) in typeList" v-if="index === 2" :key="index"
						:style="{transform: `rotate(${item.rotate}deg)`}"
						:type="item.check ? 'paperplane-filled' : 'paperplane' "
						:color="item.check ? '#ba0111' : 'black' " @tap="clickType(item, index)" size="35">
					</uni-icons>
				</div>
				<div class="button-outer bottom-right">
					<uni-icons v-for="(item, index) in typeList" v-if="index === 3" :key="index"
						:style="{transform: `rotate(${item.rotate}deg)`}"
						:type="item.check ? 'paperplane-filled' : 'paperplane' "
						:color="item.check ? '#ba0111' : 'black' " @tap="clickType(item, index)" size="35">
					</uni-icons>
				</div>

				<div class="inner-circle">
					<div class="button-inner top">
						<uni-icons type="double-up" color="black" @tap="moveBtn('top',10)" size="30"></uni-icons>
					</div>
					<div class="button-inner top-second">
						<uni-icons type="up" color="black" @tap="moveBtn('top',1)" size="36"></uni-icons>
					</div>
					<div class="button-inner left">
						<uni-icons type="double-left" color="black" @tap="moveBtn('left',10)" size="30"></uni-icons>
					</div>
					<div class="button-inner left-second">
						<uni-icons type="left" color="black" @tap="moveBtn('left',1)" size="36"></uni-icons>
					</div>
					<button @tap="sendImage" :class="['center-button', { sending: isSending }]">投图</button>
					<div class="button-inner right">
						<uni-icons type="double-right" color="black" @tap="moveBtn('right',10)" size="30"></uni-icons>
					</div>
					<div class="button-inner right-second">
						<uni-icons type="right" color="black" @tap="moveBtn('right',1)" size="36"></uni-icons>
					</div>
					<div class="button-inner bottom">
						<uni-icons type="double-down" color="black" @tap="moveBtn('buttom',10)" size="30"></uni-icons>
					</div>
					<div class="button-inner bottom-second">
						<uni-icons type="down" color="black" @tap="moveBtn('buttom',1)" size="36"></uni-icons>
					</div>
				</div>
			</div>
			<div class="bottom-buttons">
				<button @tap="resetImgData">重置图片</button>
				<!-- <button @click="checkImage">导入图片</button> -->

				<button @tap="proportionalcalculation">等比计算</button>
				<button @tap="$tab.navigateTo('/pages/webview/webview?type=syjc')">使用教程</button>
			</div>
			<div class="tips">
				侧投角度请勿过大，避免投影效果不佳
			</div>
		</div>

		<blue-link :show="showBlueLinkDialog" @close="closeblue()" :wifiInfo="wifiInfo.ssid" :istype="istype" />
		
		<compress ref="helangCompress" />

		<uni-popup ref="popup" title="选择连接方式" backgroundColor="white" :safeArea="false" type="bottom">
			<view class="box m-20 p-15-10 h-300" @click="startBlue(true)">
				<view class="title600">WIFI模式投图</view>
				<view class="p-15-10">1:请检查影描机是否连接WIFI(需和手机同一个2.4G网络)</view>
				<view class="p-15-10">
					<text>2:当前手机连接WIFI名称：</text>
					<text style="color: #e43d33"> {{wifiInfo.ssid ? wifiInfo.ssid:'未连接'}} </text>
				</view>
				<view class="p-15-10">3:请检查影描机是否被连接占用</view>
			</view>
			<view class="box m-20 p-15-10 h-300" @click="startBlue(false)">
				<view class="title600">蓝牙模式投图</view>
				<div style="display: flex;flex-direction: column;justify-content: center;height: 260rpx;">
					<view class="p-15-10">1:请检查手机是否打开蓝牙</view>
					<view class="p-15-10">2:请检查影描机是否被连接占用</view>
				</div>
			</view>
		</uni-popup>


		<uni-popup ref="popup1" title="等比计算" backgroundColor="white" :safeArea="false" type="bottom">

			<view class="title600" style="font-size: 18px;padding-top: 10px;">图片不变形纸张尺寸计算表</view>

			<view class="box m-20 p-20" style="display: flex;">
				<view class="p-20 titlebor6" v-if="imgSize">原图尺寸</view>
				<view class="p-20" v-if="imgSize" style="padding-left: 0;">宽:{{ imgSize.width.toFixed(0) }}</view>
				<view class="p-20" v-if="imgSize">高:{{ imgSize.height.toFixed(0) }}</view>
			</view>
			<view class="box m-20 p-20">
				<view style="display: flex;justify-items: center;align-items: center;margin-bottom: 20rpx;">
					<view class="titlebor6 p-20">纸张宽度</view>
					<input class="inputwifi" v-model="isk" @input="updateHeight" type="number" placeholder="请填写宽度" />
				</view>
				<view style="display: flex;justify-items: center;align-items: center;">
					<view class="titlebor6 p-20">纸张高度</view>
					<input class="inputwifi" v-model="ish" @input="updateWidth" type="number" placeholder="请填写高度" />
				</view>
			</view>
		</uni-popup>

	</view>
</template>

<script>
	import BlueLink from "@/components/BlueLink1.vue";
	import Compress from "@/components/compress.vue";
	import {
		getwem
	} from '@/api/api'
	import {
		Blue
	} from '@/utils/index.js'

	var dpr = uni.getSystemInfoSync().pixelRatio;
	var canvas, canvas2;
	var ctx, ctx2;
	var image, image2;
	var imgData, imgData2;
	export default {
		components: {
			BlueLink,
			Compress
		},
		data() {
			return {
				ischeck: false,
				isSending: false,
				count: 34,
				updatingField: '',
				isk: '', // 用户输入的宽度
				ish: '', // 用户输入的高度
				istype: false,
				selectedCorner: 0, // 默认选中左上角
				typeList: [{
						text: '左上',
						value: 0,
						rotate: 270,
						check: true
					},
					{
						text: '右上',
						value: 1,
						rotate: 0,
						check: false
					},
					{
						text: '左下',
						value: 2,
						rotate: 180,
						check: false
					},
					{
						text: '右下',
						value: 3,
						rotate: 90,
						check: false
					},
				],
				valueList: [{
						text: 'X1',
						value: '1'
					},
					{
						text: 'X5',
						value: '5'
					},
					{
						text: 'X10',
						value: '10'
					},
					{
						text: 'X30',
						value: '30'
					}
				],
				value: '1',
				imgRatio: 1, //默认图片比例
				copycorners: [], //图片初始点位拷贝
				idots: [], //图片分割点位
				corners: [{
						x: 0,
						y: 0
					}, // 左上
					{
						x: 0,
						y: 0
					}, // 右上
					{
						x: 0,
						y: 0
					}, // 左下
					{
						x: 0,
						y: 0
					} // 右下
				],
				moveStep: 1, // 移动步长基础值
				canvasMaxWidth: 1280, // rpx
				canvasMaxHeight: 720, // rpx
				showBlueLinkDialog: false,
				showwifiLinkDialog: false,
				imageSrc: '',
				imageInfo: {
					src: ""
				},
				canvasStyle: {
					width: 1280,
					height: 720
				},
				imgSize: {
					left: 0,
					top: 0,
					width: 0,
					height: 0
				},
				canvasRadio: 0, // 缩放比例
				rotateX: 0, // 垂直翻转角度
				rotateY: 0, // 水平翻转角度
				rotateAll: 0, // 旋转角度
				isFirstInit: true,
				touchCurrentScale: 1,
				isDragging: false,
				isScaling: false,
				scaleMultiplier: 1,
				lastMoveTime: 0,
				gotoname: "",
				bluename: "",
				wifissid: "",
				syjc: "",
				linkname: {
					name: "需先点这里连接影描机"
				},
				finalCorners: null,
				wifiInfo: {
					ssid: '',
				}
			}
		},
		watch: {
			// isk(newVal) {
			// 	if (newVal) {
			// 		this.ish = (newVal / this.imgSize.width * this.imgSize.height).toFixed(0);
			// 	}
			// },
			// ish(newVal) {
			// 	if (newVal) {
			// 		this.isk = (newVal / this.imgSize.height * this.imgSize.width).toFixed(0);
			// 	}
			// }
		},
		onLoad(options) {
			if (options.img) {
				this.imageSrc = options.img
				this.initImage(options.img)
				// 加载保存的点位信息
				setTimeout(() => {
					this.loadCornerPositions();
				}, 500)
			} else {
				//this.imageSrc = "https://ty.ttxcx.net/static/aaaa.png"
				//this.initImage("https://ty.ttxcx.net/static/aaaa.png")
			}
			this.getbluestatus()
			this.wifissid = uni.getStorageSync('ssid')
			this.gotocornerpostions(1)
		},
		onShow() {
			this.getbluestatus()
			this.getWifiInfo()
			this.wifissid = uni.getStorageSync('ssid')
		},
		onUnload() {
			console.log('unload')
			// 保存点位信息
			this.saveCornerPositions();
			// 推出矫正模式
			//this.gotocornerpostions(0)
			canvas.width = this.canvasMaxWidth;
			canvas.height = this.canvasMaxHeight;
		},
		mounted() {

			uni.getSetting({
				success: (res) => {
					if (!res.authSetting['scope.writePhotosAlbum']) {
						uni.authorize({
							scope: 'scope.writePhotosAlbum',
							success: () => {

							},
							fail: () => {
								uni.showModal({
									title: '提示',
									content: '需要您授权保存相册',
									showCancel: false
								});
							}
						});
					} else {

					}
				}
			});
		},
		methods: {
			getwem() {
				getwem().then(res => {
					this.syjc = res.data.syjc
				})
			},
			gotoview() {


			},
			getWifiInfo() {
				console.log('开始初始化wifi========》')
				const _that = this
				uni.startWifi({
					success(res) {
						console.log('初始化wifi成功:' + JSON.stringify(res))
						uni.getConnectedWifi({
							success(res) {
								console.error('获取wifi信息成功:' + JSON.stringify(res))
								console.log(res.wifi.SSID)
								_that.wifiInfo.ssid = res.wifi.SSID
							},
							fail(res) {
								console.error('获取wifi信息失败:' + JSON.stringify(res))
								switch (res.errCode) {
									case 12000:
										_that.startWifiError = "未先调用 startWifi 接口"
										break
									case 12001:
										_that.startWifiError = "当前系统不支持相关能力"
										break
									case 12002:
										_that.startWifiError = "密码错误"
										break
									case 12005:
										_that.startWifiError = "Android 特有，未打开 Wi-Fi 开关"
										break
									case 12012:
										_that.startWifiError =
											"系统保存的 Wi-Fi 配置过期，建议忘记 Wi-Fi 后重试，仅 Android 支持"
										break
								}
							}
						})
					},
					fail(res) {
						console.error('初始化wifi失败:' + JSON.stringify(res))
					}
				})
			},
			updateHeight() {
				if (this.updatingField !== 'height') {
					this.updatingField = 'width';
					this.ish = (this.isk / this.imgSize.width * this.imgSize.height).toFixed(0);
				}
				this.updatingField = '';
			},
			updateWidth() {
				if (this.updatingField !== 'width') {
					this.updatingField = 'height';
					this.isk = (this.ish / this.imgSize.height * this.imgSize.width).toFixed(0);
				}
				this.updatingField = '';
			},
			proportionalcalculation() {
				this.$refs.popup1.open()
			},
			gblink() {
				Blue.closeBLEConnection()
				uni.setStorageSync('bluename', "");
				// uni.setStorageSync('ssid', "");
				// uni.setStorageSync('password', "");
				uni.setStorageSync('devip', "");
				uni.setStorageSync('devid', "");
				this.getbluestatus()
			},
			getbluestatus() {
				this.bluename = uni.getStorageSync('bluename');
				this.wifissid = uni.getStorageSync('ssid');
				var devip = uni.getStorageSync('devip');
				var devid = uni.getStorageSync('devid');
				if (devip && devid) {
					this.$set(this.linkname, 'name', "WiFi模式连接中" + this.bluename);
				} else if (Blue.bleConnectDeviceID) {
					this.$set(this.linkname, 'name', "蓝牙模式连接中" + this.bluename);
				} else {
					this.$set(this.linkname, 'name', "需先点这里连接影描机");
				}

			},
			checkImage() {
				uni.chooseImage({
					count: 1,
					success: (res) => {
						this.imageSrc = res.tempFilePaths[0]
						this.initImage(res.tempFilePaths[0])
					},
				})
			},
			selecttype() {
				this.startBlue(true)
				//this.$refs.popup.open()
			},
			showPopup() {
				this.$refs.popup.open()
			},
			closeblue() {
				this.showBlueLinkDialog = false
				this.getbluestatus()
			},
			closePopup() {
				this.$refs.popup.close()
				this.getbluestatus()
			},
			startBlue(ty) {
				this.closePopup()
				this.showBlueLinkDialog = true
				this.istype = ty
			},
			startwifi() {
				this.closePopup()
				this.showwifiLinkDialog = true
			},
			// 选择角点
			clickType(clickItem, index) {
				this.typeList = this.typeList.map((item) => {
					item.check = clickItem.value === item.value;
					return item;
				});
				this.selectedCorner = clickItem.value;

				this.moveBtn('',0)
			},
			// 保存点位信息到本地存储
			saveCornerPositions() {
				console.log(JSON.stringify(this.corners), "this.corners")
				const cornerPositions = this.corners.map(corner => ({
					x: corner.x,
					y: corner.y
				}));
				console.log(JSON.stringify(cornerPositions), "cornerPositions")
				uni.setStorageSync('cornerPositions', cornerPositions);
			},

			// 从本地存储读取点位信息
			loadCornerPositions() {
				const savedCorners = uni.getStorageSync('cornerPositions');
				console.log(JSON.stringify(savedCorners), "savedCorners")
				if (savedCorners) {
					this.corners = savedCorners;
					// 绘制变形后的四边形
					this.finalCorners = [...this.corners];
					this.moveBtn('right', 0)
				}
			},
			// 移动角点
			moveBtn(direction, value, isCanvasPoint = true) {

				if (this.selectedCorner === null) {
					uni.showToast({
						title: '请先选择一个角点',
						icon: 'none'
					});
					return;
				}
				// 根据value值计算实际移动步长
				this.value = value
				const actualStep = parseInt(this.value) * this.moveStep;
				const corner = this.corners[this.selectedCorner];

				// 移动选中的角点
				switch (direction) {
					case 'top':
						corner.y = Math.max(0, Math.min(corner.y - actualStep, this.canvasMaxHeight));
						break;
					case 'right':
						corner.x = Math.max(0, Math.min(corner.x + actualStep, this.canvasMaxWidth));
						break;
					case 'left':
						corner.x = Math.max(0, Math.min(corner.x - actualStep, this.canvasMaxWidth));
						break;
					case 'buttom':
						corner.y = Math.max(0, Math.min(corner.y + actualStep, this.canvasMaxHeight));
						break;
				}


				// 清除画布并重绘
				ctx.putImageData(imgData2, 0, 0);


				// 绘制变形后的四边形
				ctx.beginPath();
				ctx.moveTo(this.corners[0].x, this.corners[0].y);
				ctx.lineTo(this.corners[1].x, this.corners[1].y);
				ctx.lineTo(this.corners[3].x, this.corners[3].y);
				ctx.lineTo(this.corners[2].x, this.corners[2].y);
				ctx.closePath();
				ctx.strokeStyle = 'rgba(41, 121, 255, 0.3)'; // 使用半透明的蓝色
				ctx.lineWidth = 0.1; // 使用更细的线条
				ctx.stroke();

				this.render()
				// 绘制角点
				if (isCanvasPoint) {
					this.corners.forEach((corner, index) => {
						ctx.beginPath();
						ctx.arc(corner.x, corner.y, 10, 0, 2 * Math.PI);
						ctx.fillStyle = this.selectedCorner === index ? 'red' : 'blue';
						ctx.fill();
						ctx.closePath();
					});
				}
				// 保存最终角点位置到本地变量
				this.finalCorners = [...this.corners];
				this.gotocornerpostions(parseInt(this.selectedCorner) + 2)
			},
			//绘制变形图片
			render() {
				const _that = this
				ctx.clearRect(0, 0, canvas.width, canvas.height);
				var ndots = this.rectsplit(this.count, this.corners[0], this.corners[1], this.corners[3], this.corners[2]);

				// 设置图像合成模式为source-over，确保图像正确叠加
				ctx.globalCompositeOperation = 'source-over';

				ndots.forEach(function(d, i) {
					//获取平行四边形的四个点
					var dot1 = ndots[i];
					var dot2 = ndots[i + 1];
					var dot3 = ndots[i + _that.count + 2];
					var dot4 = ndots[i + _that.count + 1];

					//获取初始平行四边形的四个点
					var idot1 = _that.idots[i];
					var idot2 = _that.idots[i + 1];
					var idot3 = _that.idots[i + _that.count + 2];
					var idot4 = _that.idots[i + _that.count + 1];

					if (dot2 && dot3 && i % (_that.count + 1) < _that.count) {
						//绘制三角形的下半部分
						_that.renderImage(idot3, dot3, idot2, dot2, idot4, dot4, idot1);

						//绘制三角形的上半部分
						_that.renderImage(idot1, dot1, idot2, dot2, idot4, dot4, idot1);
					}
				});
			},

			renderImage(arg_1, _arg_1, arg_2, _arg_2, arg_3, _arg_3, vertex) {
				ctx.save();

				//根据变换后的坐标创建剪切区域
				// ctx.beginPath();
				// ctx.moveTo(_arg_1.x, _arg_1.y);
				// ctx.lineTo(_arg_2.x, _arg_2.y);
				// ctx.lineTo(_arg_3.x, _arg_3.y);
				// ctx.closePath();

				// ctx.imageSmoothingEnabled = false;
				ctx.clip('evenodd');

				if (image2) {
					//传入变换前后的点坐标，计算变换矩阵
					var result = this.getMatrix.apply(this, arguments);
					//变形
					ctx.transform(result.a, result.b, result.c, result.d, result.e, result.f);

					var w = image2.width / this.count;
					var h = image2.height / this.count;
					const offset = 0.5;
					//绘制图片
					ctx.drawImage(
						image2,
						(vertex.x - this.idots[0].x) / this.imgRatio - offset,
						(vertex.y - this.idots[0].y) / this.imgRatio - offset,
						w / this.imgRatio + offset * 2,
						h / this.imgRatio + offset * 2,
						vertex.x - offset,
						vertex.y - offset,
						w + offset * 2,
						h + offset * 2
					);
				}

				ctx.restore();
			},

			/**
			 * 根据变化前后的点坐标，计算矩阵
			 * @param arg_1     变化前坐标1
			 * @param _arg_1    变化后坐标1
			 * @param arg_2     变化前坐标2
			 * @param _arg_2    变化后坐标2
			 * @param arg_3     变化前坐标3
			 * @param _arg_3    变化后坐标3
			 * @returns {{a: number, b: number, c: number, d: number, e: number, f: number}}
			 */
			getMatrix(arg_1, _arg_1, arg_2, _arg_2, arg_3, _arg_3) {

				//传入x值解第一个方程 即  X = ax + cy + e 求ace
				//传入的四个参数，对应三元一次方程：ax+by+cz=d的四个参数：a、b、c、d，跟矩阵方程对比c为1
				var arr1 = [arg_1.x, arg_1.y, 1, _arg_1.x];
				var arr2 = [arg_2.x, arg_2.y, 1, _arg_2.x];
				var arr3 = [arg_3.x, arg_3.y, 1, _arg_3.x];

				var result = this.equation(arr1, arr2, arr3);

				//传入y值解第二个方程 即  Y = bx + dy + f 求 bdf
				arr1[3] = _arg_1.y;
				arr2[3] = _arg_2.y;
				arr3[3] = _arg_3.y;

				var result2 = this.equation(arr1, arr2, arr3);

				//获得a、c、e
				var a = result.x;
				var c = result.y;
				var e = result.z;

				//获得b、d、f
				var b = result2.x;
				var d = result2.y;
				var f = result2.z;

				return {
					a: a,
					b: b,
					c: c,
					d: d,
					e: e,
					f: f
				};
			},

			/**
			 * 解三元一次方程，需要传入三组方程参数
			 * @param arr1        第一组参数
			 * @param arr2        第二组参数
			 * @param arr3        第三组参数
			 * @returns {{x: number, y: number, z: number}}
			 */
			equation(arr1, arr2, arr3) {
				var a1 = +arr1[0];
				var b1 = +arr1[1];
				var c1 = +arr1[2];
				var d1 = +arr1[3];

				var a2 = +arr2[0];
				var b2 = +arr2[1];
				var c2 = +arr2[2];
				var d2 = +arr2[3];

				var a3 = +arr3[0];
				var b3 = +arr3[1];
				var c3 = +arr3[2];
				var d3 = +arr3[3];


				// 添加小的偏移量避免除以零
				const epsilon = 1e-10;
				if (Math.abs(b2) < epsilon) b2 = epsilon;
				if (Math.abs(b3) < epsilon) b3 = epsilon;

				// 分离计算单元
				var m1 = c1 - (b1 * c2 / b2);
				var m2 = c2 - (b2 * c3 / b3);
				var m3 = d2 - (b2 * d3 / b3);
				var m4 = a2 - (b2 * a3 / b3);
				var m5 = d1 - (b1 * d2 / b2);
				var m6 = a1 - (b1 * a2 / b2);

				// 检查中间计算结果是否为 NaN 或 Infinity
				if (isNaN(m1) || isNaN(m2) || isNaN(m3) || isNaN(m4) || isNaN(m5) || isNaN(m6)) {
					console.error("Intermediate values are NaN");
					return {
						x: 0,
						y: 0,
						z: 0
					};
				}
				if (!isFinite(m1) || !isFinite(m2) || !isFinite(m3) || !isFinite(m4) || !isFinite(m5) || !isFinite(m6)) {
					console.error("Intermediate values are Infinity or -Infinity");
					return {
						x: 0,
						y: 0,
						z: 0
					};
				}


				// 计算xyz
				var denominator = (m1 / m2) * m4 - m6;
				if (Math.abs(denominator) < epsilon) {
					console.error("Denominator is too small to avoid division by zero");
					return {
						x: 0,
						y: 0,
						z: 0
					};
				}

				var x = ((m1 / m2) * m3 - m5) / denominator;
				var z = (m3 - m4 * x) / m2;
				var y = (d1 - a1 * x - c1 * z) / b1;

				return {
					x: x,
					y: y,
					z: z
				};
			},
			// 初始化角点位置
			initCorners() {

				const {
					left,
					top,
					width,
					height
				} = this.imgSize;

        console.log('初始化角点 - 图片位置:', { left, top, width, height });

				this.corners = [
          {x: left, y: (top === 0) ? 0.1 : top}, // 左上
					{x: left + width, y: (top === 0) ? 0.1 : top}, // 右上
					{x: left, y: top + height}, // 左下
					{x: left + width, y: top + height} // 右下
				];

        this.copycorners = JSON.parse(JSON.stringify(this.corners))
				this.idots = this.rectsplit(this.count, this.copycorners[0], this.copycorners[1], this.copycorners[3], this
					.copycorners[2]);

        console.log('角点位置:', this.corners);

      },
			/**
			 * 将 abcd 四边形分割成 n 的 n 次方份，获取 n 等分后的所有点坐标
			 * @param n     多少等分
			 * @param a     a 点坐标
			 * @param b     b 点坐标
			 * @param c     c 点坐标
			 * @param d     d 点坐标
			 * @returns {Array}
			 */
			rectsplit(n, a, b, c, d) {
				// ad 向量方向 n 等分
				var ad_x = (d.x - a.x) / n;
				var ad_y = (d.y - a.y) / n;
				// bc 向量方向 n 等分
				var bc_x = (c.x - b.x) / n;
				var bc_y = (c.y - b.y) / n;

				var ndots = [];
				var x1, y1, x2, y2, ab_x, ab_y;

				//左边点递增，右边点递增，获取每一次递增后的新的向量，继续 n 等分，从而获取所有点坐标
				for (var i = 0; i <= n; i++) {
					//获得 ad 向量 n 等分后的坐标
					x1 = a.x + ad_x * i;
					y1 = a.y + ad_y * i;
					//获得 bc 向量 n 等分后的坐标
					x2 = b.x + bc_x * i;
					y2 = b.y + bc_y * i;

					for (var j = 0; j <= n; j++) {
						// ab 向量为：[x2 - x1 , y2 - y1]，所以 n 等分后的增量为除于 n
						ab_x = (x2 - x1) / n;
						ab_y = (y2 - y1) / n;

						ndots.push({
							x: x1 + ab_x * j,
							y: y1 + ab_y * j,
						});
					}
				}
				return ndots;
			},
			saveCanvas(onSaveSuccess) {
				const that = this
				if (this.imageSrc === undefined || this.imageSrc === null || this.imageSrc === "") {
					this.$modal.msgError("请先选择一张图片")
					return
				}
				// 创建离屏canvas
				const offCanvas = uni.createOffscreenCanvas({
					type: '2d',
					width: this.canvasMaxWidth,
					height: this.canvasMaxHeight
				})
				const offCtx = offCanvas.getContext('2d')

				// 填充黑色背景
				offCtx.fillStyle = 'black'
				offCtx.fillRect(0, 0, this.canvasMaxWidth, this.canvasMaxHeight)
				// 绘制当前canvas的内容到新的canvas上
				offCtx.drawImage(canvas, 0, 0, this.canvasMaxWidth, this.canvasMaxHeight);
				// 转换为临时文件路径
				uni.canvasToTempFilePath({
					x: 0,
					y: 0,
					width: this.canvasMaxWidth,
					height: this.canvasMaxHeight,
					destWidth: this.canvasMaxWidth,
					destHeight: this.canvasMaxHeight,
					quality: 1,
					canvas: offCanvas,
					success(res) {
						console.log(res)
						if (onSaveSuccess) {
							onSaveSuccess(res);
						}
					},
					fail(err) {
						that.$modal.msgError("图片生成失败")
						console.error(err)
					}
				}, that)
			},
			gotocornerpostions(state) {

        console.log('state :', state);

				if (!Blue.bleConnectDeviceID) {
					uni.showToast({
						title: '请先连接影描机',
						icon: 'none',
					});
					return;
				}

				const scale = this.canvasRadio;
				const cornerPositions = this.corners.map(corner => ({
					x: Math.round(corner.x / scale),
					y: Math.round(corner.y / scale)
				}));
				// 构建发送数据
				const cornerData = {
					leftTop: cornerPositions[0],
					rightTop: cornerPositions[1],
					leftBottom: cornerPositions[2],
					rightBottom: cornerPositions[3]
				};
				console.log('Corner positions:', JSON.stringify(cornerData));
				console.log('this.corners :', JSON.stringify(this.corners));

				var x1 = parseInt(this.corners[0].x)
				var y1 = parseInt(this.corners[0].y)
				var x2 = parseInt(this.corners[1].x)
				var y2 = parseInt(this.corners[1].y)
				var x3 = parseInt(this.corners[2].x)
				var y3 = parseInt(this.corners[2].y)
				var x4 = parseInt(this.corners[3].x)
				var y4 = parseInt(this.corners[3].y)


				Blue.setCorrectUpdateBLE(state, x1, y1, x2, y2, x3, y3, x4, y4).then(
					res => {
						console.log('矫正信息返回:', res)
					});

				// var devip = uni.getStorageSync('devip');
				// var devid = uni.getStorageSync('devid');

				// if (devip && devid) {
				// 	console.log("使用WIFI模式传送坐标：发现了设备IP和设备ID ")
				// 	var that = this;
				// 	let param = "";
				// 	param += "x1=" + x1 + "&y1=" + y1 + "&x2=" + x2 + "&y2=" + y1 + "&x3=" + x3 +
				// 		"&y3=" + y3 + "&x4=" + x4 + "&y4=" + y4 + "&dir=" + this.selectedCorner + "&state=" + state
				// 	console.log("发送param", param)
				// 	console.log('http://' + devip + '/correct_pos?' + param)
				// 	uni.request({
				// 		url: 'http://' + devip + '/correct_pos?' + param,
				// 		method: 'get', //请求的方式
				// 		success: (res) => { //请求成功之后的回调函数
				// 			console.log(res) //查看真实数据 console.log(res.data)
				// 		}
				// 	})

				// } else {
				// 	console.log("使用蓝牙发送坐标", state, x1, y1, x2, y2, x3, y3, x4, y4)
				// 	Blue.setCorrectUpdateBLE(state, x1, y1, x2, y2, x3, y3, x4, y4).then(
				// 		res => {
				// 			console.log('矫正信息返回:', res)
				// 		});
				// }

			},
			sendImage() {
				this.ischeck = true
				//重新调用一次绘制方法，防止辅助线边线被绘制
				this.moveBtn('buttom', 0, false)

				if (!Blue.bleConnectDeviceID) {
					uni.showToast({
						title: '请先连接影描机',
						icon: 'none',
					});
					this.ischeck = false
					return;
				}

				if (this.isSending) {
					console.log("Button is currently disabled.");
					this.ischeck = false
					return;
				}
				console.log("Sending started.");
				this.isSending = true;


				const scale = this.canvasRadio;
				const cornerPositions = this.corners.map(corner => ({
					x: Math.round(corner.x / scale),
					y: Math.round(corner.y / scale)
				}));
				// 构建发送数据
				const cornerData = {
					leftTop: cornerPositions[0],
					rightTop: cornerPositions[1],
					leftBottom: cornerPositions[2],
					rightBottom: cornerPositions[3]
				};
				console.log('Corner positions:', cornerData);

				var x1 = parseInt(this.corners[0].x)
				var y1 = parseInt(this.corners[0].y)
				var x2 = parseInt(this.corners[1].x)
				var y2 = parseInt(this.corners[1].y)
				var x3 = parseInt(this.corners[2].x)
				var y3 = parseInt(this.corners[2].y)
				var x4 = parseInt(this.corners[3].x)
				var y4 = parseInt(this.corners[3].y)

				this.saveCanvas((res) => {
					const path = res.tempFilePath
					// 单张压缩
					this.$refs.helangCompress.compress({
						src: path,
						maxSize: 1000,
						fileType: 'jpg',
						quality: 1,
						minSize: 100 //最小压缩尺寸，图片尺寸小于该时值不压缩，非H5平台有效。若需要忽略该设置，可设置为一个极小的值，比如负数。
					}).then((res) => {
						// 压缩成功回调
						//console.log(res, "从canvas中提取后再压缩后的图片")
						var devip = uni.getStorageSync('devip');
						var devid = uni.getStorageSync('devid');
						if (devip && devid) {
							console.log("使用WIFI模式传送：发现了设备IP和设备ID ")
							//更新坐标位置
							// x1, y1: 左上( 0,0), x2,y2:右上(480,0)
							// x3,y3: 右下(480,480), x4, y4:左下(0,480)
							var that = this;
							// let param = "";
							// param += "x1=" + x1 + "&y1=" + y1 + "&x2=" + x2 + "&y2=" + y1 + "&x3=" + x3 +
							// 	"&y3=" + y3 + "&x4=" + x4 + "&y4=" + y4 + "&dir=" + this.selectedCorner
							// console.log("发送param", param)
							// console.log('http://' + devip + '/correct_pos?state=1&' + param)
							// uni.request({
							// 	url: 'http://' + devip + '/correct_pos?state=1&' + param,
							// 	method: 'get', //请求的方式
							// 	success: (res) => { //请求成功之后的回调函数
							// 		console.log(res) //查看真实数据 console.log(res.data)
							// 	}
							// })
							console.log("IP WIFI名", devip, devid)
							console.log('http://' + devip + '/playimg')
							uni.uploadFile({
								url: 'http://' + devip + '/playimg', // 上传的接口地址
								filePath: res,
								name: 'file',
								formData: {
									'user': 'test'
								},
								success: function(res) {
									this.ischeck = false
									console.log(res.data); // 上传成功后的响应数据
								},
								fail: function(error) {
									// 处理上传失败的错误
									console.error('上传失败', error);
									if (error.errMsg.includes('net::ERR_CONNECTION')) {
										// 网络错误处理
										console.log('网络连接问题，请检查网络连接');
									} else if (error.errMsg.includes('404')) {
										// 服务器端错误处理
										console.log('服务器未找到上传地址');
									} else {
										// 其他错误处理
										console.log('其他错误：', error);
									}
								},
							})


						} else {
							console.log("使用蓝牙模式传送")
							Blue.readFile(res, (buffer) => {
								Blue.sendBinaryFile(buffer)
							});
							this.ischeck = false
							// console.log("发送坐标", parseInt(this.selectedCorner) + 2, x1, y1, x2, y2, x3, y3,
							// 	x4, y4)
							// Blue.setCorrectUpdateBLE(parseInt(this.selectedCorner) + 2, x1, y1, x2, y2, x3,
							// 	y3, x4,
							// 	y4).then(res => {
							// 	console.log('矫正信息返回:', res)
							// });

						}
					}).catch((err) => {
						this.ischeck = false
						console.log(err)
						uni.showToast({
							title: '图片压缩失败',
							icon: 'none',
						});
						// 压缩失败回调
					})

				})
				setTimeout(() => {
					this.isSending = false; // Re-enable the button after 2 seconds
					console.log("Sending enabled again.");
				}, 2000);
			},

			async initImage(url) {
				this.imageInfo = await this.getImageInfo(url)
				console.log('imageInfo', JSON.stringify(this.imageInfo))
				if (!this.imageInfo.path) return
				await new Promise((resolve) => {
					this.$nextTick(() => {
						setTimeout(() => {
							resolve()
						}, 200)
					})
				})
				let canvasSq = await new Promise((resolve) => {
					uni.createSelectorQuery().in(this).select('#imageCanvas').boundingClientRect()
						.exec(
							rect => {
								delete rect[0].dataset;
								resolve(rect[0])
							})
				})
				canvas = await new Promise((resolve) => {
					uni.createSelectorQuery().in(this).select('#imageCanvas')
						.fields({
							node: true,
							size: true
						}).exec((res) => {
							resolve(res[0].node || res[0])
						})
				});
				canvas2 = await new Promise((resolve) => {
					uni.createSelectorQuery().in(this).select('#imageCanvasHide')
						.fields({
							node: true,
							size: true
						}).exec((res) => {
							resolve(res[0].node || res[0])
						})
				});

				// 修改图片尺寸和位置的计算
				this.imgRatio = Math.min(
					this.canvasStyle.width / this.imageInfo.width,
					this.canvasStyle.height / this.imageInfo.height
				);

				// 计算居中位置
				const scaledWidth = this.imageInfo.width * this.imgRatio;
				const scaledHeight = this.imageInfo.height * this.imgRatio;
				const centerLeft = (this.canvasStyle.width - scaledWidth) / 2;
				const centerTop = (this.canvasStyle.height - scaledHeight) / 2;

				this.imgSize = {
					left: centerLeft,
					top: centerTop,
					width: scaledWidth,
					height: scaledHeight
				};

				console.log("this.imgSize", this.imgSize)

				this.initCorners();

				canvas.width = this.canvasMaxWidth;
				canvas.height = this.canvasMaxHeight;
				canvas2.width = canvas.width;
				canvas2.height = canvas.height;
				ctx = canvas.getContext('2d')
				ctx2 = canvas2.getContext('2d')
			//	this.canvasRadio = canvas.width / this.canvasStyle.width
        this.canvasRadio = 1
				console.log("canvas.width", canvas.width)
				console.log("canvas.height", canvas.height)
				console.log("radio", this.canvasRadio)
				ctx.scale(this.canvasRadio, this.canvasRadio)
				ctx2.scale(this.canvasRadio, this.canvasRadio)
				await this.drawCanvas()
				
				this.gotocornerpostions(1)

			},

			async drawCanvas() {

				let that = this;

				console.log('imgSize', JSON.stringify(this.imgSize))

				await new Promise((resolve, reject) => {
					image = canvas.createImage()
					image.onload = () => {
						resolve()
					}
					image.src = that.imageInfo.path
				});
				await new Promise((resolve, reject) => {
					image2 = canvas2.createImage()
					image2.onload = () => {
						resolve()
					}
					image2.src = that.imageInfo.path
				});

				ctx.clearRect(0, 0, canvas.width, canvas.height)
				ctx2.clearRect(0, 0, canvas.width, canvas.height)

				ctx.fillStyle = 'black'; // 设置背景颜色为黑色
				ctx.fillRect(0, 0, canvas.width, canvas.height);


				const rotateAllRadians = this.rotateAll * Math.PI / 180;
				// 根据旋转条件绘制图片
				//this.drawImageWithRotation(ctx, image, imgSize, rotateAllRadians, this.rotateX, this.rotateY);
				ctx.drawImage(image, this.imgSize.left, this.imgSize.top, this.imgSize.width, this.imgSize.height);
				ctx2.drawImage(image, this.imgSize.left, this.imgSize.top, this.imgSize.width, this.imgSize.height);
				imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
				imgData2 = ctx2.getImageData(0, 0, canvas.width, canvas.height);

			},


			/**
			 * 获取图片信息
			 * */
			async getImageInfo(url) {
				let info = {};
				if (url.startsWith("http")) url = await new Promise((resolve, reject) => {
					uni.downloadFile({
						url,
						success(e) {
							resolve(e.tempFilePath)
						},
						fail(err) {
							url = ""
							console.error("下载图片失败", err)
						}
					})
				})
				if (!url) return;
				info = await new Promise((resolve, reject) => {
					uni.getImageInfo({
						src: url,
						success(info) {
							resolve(info);
						},
						fail(err) {
							console.error("获取图片失败", err)
						}
					})
				})
				return info
			},
			/**
			 * 重置ImgData
			 * */
			resetImgData() {
				this.gotocornerpostions(0)
				if (this.imageSrc === undefined || this.imageSrc === null || this.imageSrc === "") {
					this.$modal.msgError("请先选择一张图片")
					return
				}
				imgData = ctx2.getImageData(0, 0, canvas.width, canvas.height);
				ctx.putImageData(imgData, 0, 0)
				this.initCorners()
				// this.corners = this.copycorners
        setTimeout(() => {
					this.gotocornerpostions(1)

        }, 500)

        setTimeout(()=>{
          this.gotocornerpostions(2)
        },1000)

        setTimeout(()=>{
          this.gotocornerpostions(3)
        },1500)

        setTimeout(()=>{
          this.gotocornerpostions(4)
        },2000)

        setTimeout(()=>{
          this.gotocornerpostions(5)
        },2500)

			},
			resetCanvas() {
				this.isFirstInit = true
				this.canvasRadio = 0
				this.rotateX = 0
				this.rotateY = 0
				this.rotateAll = 0
				this.touchCurrentScale = 1
				this.imgSize.left = 0
				this.imgSize.top = 0
				this.resetImgData()
				this.drawCanvas()
			},
			resetFileTranse() {
				Blue.onResetFileTranse()
			},

		},
	}
</script>
<style scoped>
	body {
		display: flex;
		align-items: center;
		justify-content: center;
		min-height: 100vh;
		margin: 0;
		background-color: white;
	}

	.sending {
		color: #fff;
		background-color: red !important;
	}

	.titlebor6 {
		border: 1px solid #000;
		display: inline-block;
		border-radius: 6px;
		margin-right: 10px;
	}

	page {
		background: #fff;
	}

	.container {
		display: flex;
		flex-direction: column;
		align-items: center;
		gap: 1rem;
	}

	.outer-circle {
		position: relative;
		width: 320px;
		height: 320px;
		background-color: #f3f4f6;
		display: flex;
		align-items: center;
		justify-content: center;
		border: 1px solid #000;
	}

	.inner-circle {
		position: relative;
		width: 280px;
		height: 280px;
		background-color: #e5e7eb;
		border-radius: 50%;
		display: flex;
		align-items: center;
		justify-content: center;
	}

	button {
		width: 48px;
		height: 48px;
		background-color: white;
		border: none;
		border-radius: 50%;
		box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
		display: flex;
		align-items: center;
		justify-content: center;
		cursor: pointer;
	}

	.center-button {
		width: 64px;
		height: 64px;
	}

	.button-outer {
		position: absolute;
	}

	.button-outer.top-left {
		top: 16px;
		left: 16px;
		DISPLAY: flex;
	}

	.button-outer.top-right {
		top: 16px;
		right: 16px;
		DISPLAY: flex;
	}

	.button-outer.bottom-left {
		bottom: 16px;
		left: 16px;
		DISPLAY: flex;
	}

	.button-outer.bottom-right {
		bottom: 16px;
		right: 16px;
		DISPLAY: flex;
	}

	.button-inner {
		position: absolute;
		width: 48px;
		height: 48px;
		background-color: white;
		border: none;
		border-radius: 50%;
		box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
		display: flex;
		align-items: center;
		justify-content: center;
		cursor: pointer;
	}

	.button-inner :hover {
		background-color: red;
		width: 48px;
		height: 48px;
		border-radius: 50%;
		display: flex;
		align-items: center;
		justify-content: center;
		cursor: pointer;
	}

	.button-inner.top {
		top: 4px;
		transform: translateX(-50%);
		left: 50%;
	}

	.button-inner.top-second {
		top: 56px;
		transform: translateX(-50%);
		left: 50%;
	}

	.button-inner.bottom {
		bottom: 4px;
		transform: translateX(-50%);
		left: 50%;
	}

	.button-inner.bottom-second {
		bottom: 56px;
		transform: translateX(-50%);
		left: 50%;
	}

	.button-inner.left {
		left: 4px;
		transform: translateY(-50%);
		top: 50%;
	}

	.button-inner.left-second {
		left: 56px;
		transform: translateY(-50%);
		top: 50%;
	}

	.button-inner.right {
		right: 4px;
		transform: translateY(-50%);
		top: 50%;
	}

	.button-inner.right-second {
		right: 56px;
		transform: translateY(-50%);
		top: 50%;
	}

	.bottom-buttons {
		display: flex;
		gap: 1rem;
	}

	.bottom-buttons button {
		border-radius: 4px;
		width: auto;
		height: auto;
	}
	
	.tips {
		font-size: 16px;
		font-weight: 400;
		color: #FF6B6B;
	}
</style>
<style lang="scss">
	.bg {
		width: 100%;
		background-color: white;
		height: 800rpx;
		padding: 20rpx;
	}

	.title600 {
		text-align: center;
		font-size: 30px;
		font-weight: 600;
		margin-top: 10rpx;
	}

	.bluetoothBox {
		height: 160rpx;
		margin: 20rpx;
		background-color: white;
		border-radius: 10rpx;
		box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
		display: flex;
		padding: 20rpx;
		align-items: center;
	}

	.bluetoothBox .left {
		flex: 1;
	}

	.item_title {
		font-size: 30rpx;
		color: #333;
		margin: 15rpx 0;
	}

	.item_subtitle {
		font-size: 26rpx;
		color: #666;
		margin: 15rpx 0;
	}

	.connect-btn {
		width: 150rpx;
		height: 60rpx;
		background-color: #409EFF;
		color: white;
		border-radius: 30rpx;
		text-align: center;
		line-height: 60rpx;
		margin: auto 20rpx;
	}
</style>
<style lang="scss">
	.corner-indicators {
		position: absolute;
		top: 10rpx;
		left: 10rpx;
		display: flex;
		gap: 10rpx;
	}

	.h-300 {
		height: 340rpx;
	}

	.corner-indicator {
		width: 20rpx;
		height: 20rpx;
		border-radius: 50%;
		border: 2rpx solid #000;
		background: #fff;

		&.active {
			background: #2979ff;
		}
	}
</style>
<style lang="scss">
	.imageCanvas {
		width: 750rpx;
    height: 421.875rpx;  /* 修改了这一行 */
		background: black;
	}

	.canvasHide {
		z-index: 1;
		opacity: 0;
		position: absolute;
		top: -2000px;
		left: -2000px;
		transform: initial;
	}

	.connect-box {
		display: flex;
		border: black 1px solid;
		border-radius: 20rpx;
		height: 70rpx;
		margin: 20rpx 40rpx;
		overflow: hidden
	}

	.connect-box-state {
		width: 150rpx;
		height: 70rpx;
		line-height: 70rpx;
		text-align: center;
		background: #F56C6C;
		//background: #67C23A;
		color: black
	}

	.connect-box-x {
		width: 70rpx;
		height: 70rpx;
		line-height: 70rpx;
		text-align: center;
		color: black;
		font-weight: bold;
		border-left: black 1px solid;
		border-right: black 1px solid;
	}

	.connect-box-select-device {
		flex: 1;
		height: 70rpx;
		line-height: 70rpx;
		text-align: center;
		color: black;
	}

	.uni-data-checklist .checklist-group .checklist-box.is--tag {
		padding: 20rpx 40rpx !important;
		border-radius: 10rpx !important;
	}

	.button-group {
		padding-top: 20rpx;
		width: 100%;
		height: 450rpx;
		display: flex;
		justify-content: center;
	}

	.outter-circle {
		border: black 1rpx solid;
		position: relative;
		margin-left: 10rpx;
		width: 420rpx;
		height: 420rpx;
		background-color: lightcyan;
		border-radius: 100%;
		overflow: hidden;
		transform-origin: center;
		transform: rotate(45deg);
	}

	.inner-parts {
		float: left;
		width: 208rpx;
		height: 208rpx;
		line-height: 208rpx;
		text-align: center;
		border: black 1rpx solid;
	}

	.silver {
		background-color: silver;
	}

	.gold {
		background-color: gold;
	}

	.blue {
		background-color: blue;
	}

	.brown {
		background-color: brown;
	}

	// .inner-circle {
	// 	position: absolute;
	// 	margin-top: 105rpx;
	// 	margin-left: 105rpx;
	// 	width: 210rpx;
	// 	height: 210rpx;
	// 	line-height: 210rpx;
	// 	text-align: center;
	// 	border-radius: 100%;
	// 	background-color: lightblue;
	// 	border: black 1rpx solid;
	// }

	.rotate {
		display: inline-block;
		transform: rotate(-45deg);
	}

	.rotate-315 {
		display: inline-block;
		transform: rotate(-315deg);
	}

	.btn2 {
		width: 300rpx;
		margin: 15rpx;
		height: 80rpx;
		background-color: #fff;
		border-radius: 10rpx;
		border: black 1px solid;
		line-height: 80rpx;
		font-size: 28rpx;
		text-align: center;
	}
</style>